#include <iostream>
#include <vector>
#include <memory>
#include <mutex>
#include <condition_variable>

template <typename T>
class ObjectPool {
public:
    ObjectPool(size_t maxSize) : maxSize(maxSize) {}

    // 获取对象
    std::shared_ptr<T> acquire() {
        std::unique_lock<std::mutex> lock(mtx);

        // 等待直到池中有可用对象或可以创建新对象
        cv.wait(lock, [this]() { return !pool.empty() || currentSize < maxSize; });

        if (!pool.empty()) {
            // 从池中获取对象
            auto obj = pool.back();
            pool.pop_back();
            return obj;
        } else {
            // 创建新对象
            ++currentSize;
            return std::shared_ptr<T>(new T(), [this](T* ptr) {
                release(ptr);
            });
        }
    }

    // 释放对象
    void release(T* obj) {
        std::unique_lock<std::mutex> lock(mtx);
        pool.push_back(std::shared_ptr<T>(obj));
        cv.notify_one();
    }

private:
    std::vector<std::shared_ptr<T>> pool; // 对象池
    size_t maxSize;                       // 池的最大大小
    size_t currentSize = 0;               // 当前对象数量
    std::mutex mtx;                       // 互斥锁
    std::condition_variable cv;           // 条件变量
};

// 示例对象类
class MyObject {
public:
    MyObject() {
        std::cout << "MyObject created\n";
    }
    ~MyObject() {
        std::cout << "MyObject destroyed\n";
    }
    void doSomething() {
        std::cout << "Doing something\n";
    }
};

int main() {
    ObjectPool<MyObject> pool(5); // 最大池大小为 5

    // 获取对象
    auto obj1 = pool.acquire();
    obj1->doSomething();

    // 释放对象
    //pool.release(obj1.get());

    // 再次获取对象
    auto obj2 = pool.acquire();
    obj2->doSomething();



    return 0;
}

